package com.zuikaku.nettychat.netty.controller;

import com.zuikaku.nettychat.netty.framework.BaseController;
import com.zuikaku.nettychat.netty.framework.NettyClient;
import com.zuikaku.nettychat.netty.framework.NettyServer;
import com.zuikaku.nettychat.netty.vo.MethodType;
import com.zuikaku.nettychat.pojo.Chat;
import com.zuikaku.nettychat.pojo.User;
import com.zuikaku.nettychat.service.ChatService;
import com.zuikaku.nettychat.utils.ResponseJson;
import com.zuikaku.nettychat.vo.ChatVO;
import io.netty.channel.socket.SocketChannel;
import org.json.JSONArray;
import org.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class ChatController extends BaseController {

    public static SimpleDateFormat sdf =new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    @Autowired
    private NettyServer nettyServer;

    @Autowired
    private ChatService chatService;

    public String startChat(String data, SocketChannel socketChannel) {
        JSONObject requestJsonObj = new JSONObject(data);
        int opponentId = requestJsonObj.getInt("opponentId");
        int currentUserId = nettyServer.getSocketChannelNettyClientMap().get(socketChannel).getActiveUser().getUserId();
        //关联查询
        ChatVO chatVO = chatService.selectChatVOByBothId(currentUserId, opponentId);
        if (chatVO == null) {
            //说明尚未进行过聊天,新建该记录进行返回
            Chat newChat = new Chat();
            newChat.setFkSenderId(currentUserId);
            newChat.setFkReceiverId(opponentId);
            newChat.setType("read");
            Date nowDate = new Date();
            newChat.setCreateTime(nowDate);
            newChat.setUpdateTime(nowDate);
            newChat.setHistoryChat("[]");//设置为一个空数组(json)
            int res = chatService.addChatByChat(newChat);
            if(res==0){
                return ResponseJson.fail("开启聊天失败");
            }
            chatVO = chatService.selectChatVOByPKForSender(newChat.getChatId());//for Sender意味着将receiverId与user表关联查出用户
        }
        return ResponseJson.success("返回已有聊天记录", new JSONObject(chatVO));
    }


    /**
     * 发送时查找对方SocketChannel是否存在，存在要主动通知对方（主动发出响应）
     * @param data
     * @param socketChannel
     * @return
     */
    public String sendMsg(String data,SocketChannel socketChannel){
        JSONObject requestJsonObj =new JSONObject(data);
        int chatId =requestJsonObj.getInt("chatId");
        String msg =requestJsonObj.getString("msg");
        Chat chat = chatService.selectChatByPK(chatId);
        //获得当前用户信息，并判断出对方用户
        User currentUser = nettyServer.getSocketChannelNettyClientMap().get(socketChannel).getActiveUser();
        int opponentId =-1;
        if(chat.getFkSenderId().equals(currentUser.getUserId())){
            opponentId=chat.getFkReceiverId();
        }else if(chat.getFkReceiverId().equals(currentUser.getUserId())){
            opponentId=chat.getFkSenderId();
        }
        //对chat记录进行更新
        chat.setType("unread");
        Date nowDate = new Date();
        chat.setUpdateTime(nowDate);
        JSONArray historyMsgJsonArray = new JSONArray(chat.getHistoryChat());
        JSONObject newMsgJsonObj =new JSONObject();
        newMsgJsonObj.put("userId",currentUser.getUserId());
        newMsgJsonObj.put("content",msg);
        newMsgJsonObj.put("time",sdf.format(nowDate));
        historyMsgJsonArray.put(newMsgJsonObj);
        chat.setHistoryChat(historyMsgJsonArray.toString());

        int res = chatService.updateChatByChat(chat);

        if(res>0) {
            //判断对方用户是否在线（尝试查询其NettyClient）
            int finalOpponentId = opponentId;
            List<NettyClient> opponentClientList = nettyServer.getOnlineNettyClientList().stream().filter(p -> p.getActiveUser().getUserId() == finalOpponentId).collect(Collectors.toList());
            if (opponentClientList.size() != 0) {
                //对其主动发送消息
                //构造推送Request(ReceiveRequest【无SendRequest方法】)
                opponentClientList.forEach(p -> {
                    NettyServer.sendResponseToClient(ResponseJson.success("收到消息", newMsgJsonObj), MethodType.RECEIVE_MSG, p.getSocketChannel());
                });

            }
            //为当前客户端返回发送成功
            return ResponseJson.success("发送成功",newMsgJsonObj);

        }else {
            //为当前客户端返回发送失败
            return ResponseJson.fail("发送失败");
        }



    }

}
